#!/usr/bin/env python
#
# Copyright 2010 Per Olofsson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import sys
import os
import optparse
import plistlib
import time

from autopkglib import BUNDLE_ID
from autopkglib import get_all_prefs
from autopkglib import AutoPackagerError, AutoPackager


def main(argv):
    # Parse arguments.
    p = optparse.OptionParser()
    p.set_usage("Usage: %prog [options] recipe.plist [key=value key=value ...]")
    p.add_option("-v", "--verbose", action="count", default=1,
                 help="Verbose output.")
    p.add_option("-q", "--quiet", action="store_true",
                 help="Be quiet.")
    options, argv = p.parse_args(argv)
    if len(argv) < 2:
        print >> sys.stderr, p.get_usage()
        return 1
    
    recipe_path = argv[1]
    
    if options.quiet:
        options.verbose = 0
    
    try:
        recipe = plistlib.readPlist(recipe_path)
    except BaseException as e:
        print >> sys.stderr, "Can't read %s: %s" % (recipe_path, e)
        return 1
    
    # Obtain prefs from the defaults domain
    prefs = get_all_prefs()
    
    # Add RECIPE_PATH and RECIPE_DIR variables for use by processors
    prefs["RECIPE_PATH"] = os.path.abspath(recipe_path)
    prefs["RECIPE_DIR"] = os.path.dirname(os.path.abspath(recipe_path))
    
    # Add our verbosity level
    prefs["verbose"] = options.verbose
    
    # Add variables from commandline.
    cli_values = {}
    for arg in argv[2:]:
        (key, sep, value) = arg.partition("=")
        if sep != "=":
            print >> sys.stderr, "Invalid variable [key=value]: %s" % arg
            print >> sys.stderr, p.get_usage()
            return 1
        cli_values[key] = value
    
    autopackager = AutoPackager(options, prefs)
    
    exit_status = 0
    exit_string = ""
    
    try:
        autopackager.process_input_overrides(recipe, cli_values)
        autopackager.verify(recipe)
        autopackager.process(recipe)
    except AutoPackagerError as e:
        exit_status += 1
        exit_string = str(e)
        print >> sys.stderr, e
        
    
    # build a pathname for a receipt
    recipe_basename = os.path.splitext(os.path.basename(recipe_path))[0]
    receipt_dir = os.path.join(autopackager.env["RECIPE_CACHE_DIR"], "receipts")
    timestamp = time.strftime("%Y%m%d-%H%M%S")
    receipt_name = "%s-receipt-%s.plist" % (recipe_basename, timestamp)
    if not os.path.exists(receipt_dir):
        try:
            os.makedirs(receipt_dir)
        except OSError, e:
            exit_status += 1
            print >> sys.stderr, (
                "Can't create %s: %s" % (receipt_dir, e.strerror))
            return exit_status
            
    receipt_path = os.path.join(receipt_dir, receipt_name)
    try:
        plistlib.writePlist({
                "Exit Status": exit_status,
                "Exit String": exit_string,
                "Receipt": autopackager.results
            }, receipt_path)
        if options.verbose:
            print "Receipt written to %s" % receipt_path
    except IOError as e:
        exit_status += 1
        print >> sys.stderr, (
            "Can't write receipt to %s: %s" % (receipt_path, e.strerror))
    except Exception:
        print >> sys.stderr, {
                "Exit Status": exit_status,
                "Exit String": exit_string,
                "Receipt": autopackager.results
                }
    
    return exit_status
    

if __name__ == "__main__":
    sys.exit(main(sys.argv))
    
